<?php

namespace App\Kuafu\Shop\Controller\B;

use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Common\Enum\CommonCodeEnum;
use App\Kuafu\Common\Exceptions\UploadImageException;
use App\Kuafu\Common\Service\InformationPushService;
use App\Kuafu\Shop\Enum\CameraCacheEnum;
use App\Kuafu\Shop\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Model\CameraModel;
use App\Kuafu\Shop\Service\CameraLibrary\CameraFactory;
use App\Kuafu\Shop\Service\DeviceCameraService;
use App\Kuafu\Shop\Service\ShopCameraService;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\User\Service\UserRoleService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class CameraController extends BaseController
{
    /**
     * 上传校验文件
     *
     * @param Request $request
     * @return JsonResponse
     * @throws UploadImageException
     */
    public function check(Request $request): JsonResponse
    {
        $file               = $request->file('file');
        $allowed_extensions = ['csv', 'xlsx', 'xls'];
        if (!in_array(strtolower($file->getClientOriginalExtension()), $allowed_extensions)) {
            throw new UploadImageException(CommonCodeEnum::ERR_UPLOAD_IMAGE_EXT_ERROR,
                '只能上传 ' . implode(',', $allowed_extensions) . ' 格式的文件.');
        }

        $tempData = $file->getContent();

        $file     = md5($file->getClientOriginalName()) . date('YmdHis',
                time()) . "." . $file->getClientOriginalExtension();
        $filePath = ShopCameraService::getTempDir() . $file;
        file_put_contents($filePath, $tempData);

        $excelResult = ShopCameraService::checkExcelContent($filePath);

        return $this->success([
            'fileName'    => $file,
            'successList' => $excelResult['successList'],
            'failureList' => $excelResult['failureList'],
            'shopCount'   => count($excelResult['shopList'])
        ]);
    }

    /**
     * 导入对应的文件
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function import(Request $request): JsonResponse
    {
        $file     = $request->get('fileName');
        $filePath = ShopCameraService::getTempDir() . $file;
        $list     = ShopCameraService::checkExcelContent($filePath);

        $result = ShopCameraService::saveCameraList($list['successList']);

        if ($result) {
            try {
                $shopIds = array_column($list['successList'], 'shopId');
                $shopIds = array_unique($shopIds);


                foreach ($shopIds as $shopId) {
                    // 推送消息
                    $userIds = UserRoleService::getShopManageList(config('merchant.manager_role_id'),
                        [$shopId])['lists'] ?? [];

                    InformationPushService::push(
                        InformationPushService::ALY_MONITOR_OPEN_PUSH,
                        array_column($userIds, 'userId'),
                        ShopService::getShopInfo($shopId)
                    );

                    // 删除缓存
                    Cache::forget(CameraCacheEnum::getCameraListCacheKey((int)$shopId));
                }

                return $this->success();
            } catch (Exception $exception) {
                return $this->fail(1);
            }
        } else {
            return $this->fail(0);
        }

    }

    public function update(Request $request): JsonResponse
    {
        $list   = $request->get('cameraList');
        $shopId = (int)$request->get('shopId');
        foreach ($list as $item) {
            foreach (CodeEnum::SHOP_CAMERA_TRIPLE_TYPE_TEXT as $key => $value) {
                if (!empty($item['deviceName' . $key])) {
                    CameraModel::query()->where(
                        [
                            'shopId'     => $shopId,
                            'name'       => $item['name'],
                            'tripleType' => $key
                        ]
                    )->update([
                        'productKey'   => $item['productKey' . $key] ?? '',
                        'deviceName'   => $item['deviceName' . $key] ?? '',
                        'deviceSecret' => $item['deviceSecret' . $key] ?? '',
                        'mac'          => $item['mac'] ?? '',
                    ]);
                }
            }
        }

        Cache::forget(CameraCacheEnum::getCameraListCacheKey($shopId));

        return $this->success();
    }

    public function cruiseCameraList(Request $request): JsonResponse
    {
        $shopId              = (int)$request->get('shopId');
        $isNew               = (int)$request->get('isNew', 0);
        $deviceCameraService = new DeviceCameraService($this->brandId, $shopId);
        return $this->success($deviceCameraService->getCameraListByShopId($isNew));
    }

    /**
     * @throws Exception
     */
    public function cruiseCameraInfo(Request $request): JsonResponse
    {
        $deviceId = (int)$request->get('deviceId');
        $scheme   = $request->get('scheme', 'hls');
        $clarity  = $request->get('clarity', CodeEnum::CLARITY_TYPE_FLUENCY);
        if (!$deviceId) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INPUT);
        }
        $deviceCameraService = new DeviceCameraService();

        $fluency        = $deviceCameraService->getCameraIdById($deviceId, $scheme);
        $highDefinition = $deviceCameraService->getCameraIdById($deviceId, $scheme,
            CodeEnum::CLARITY_TYPE_HIGH_DEFINITION);

        $fluency['fluencyStreamUrl']        = $fluency['streamUrl'];
        $fluency['highDefinitionStreamUrl'] = $highDefinition['streamUrl'];

        return $this->success($fluency);
    }

    /**
     * @throws Exception
     */
    public function cruiseCameraRecordDate(Request $request): JsonResponse
    {
        $deviceId      = (int)$request->get('deviceId');
        $date          = $request->get('date', date('Y-m-d'));
        $dateTimestamp = strtotime($date);

        if (!$deviceId) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INPUT);
        }


        $deviceCameraService = new DeviceCameraService();
        return $this->success($deviceCameraService->queryDeviceVodUrlByTimeByInvoke($deviceId, $dateTimestamp));
    }

    /**
     * @throws Exception
     */
    public function cruiseCameraRecordPlay(Request $request): JsonResponse
    {
        $deviceId    = (int)$request->get('deviceId');
        $scheme      = $request->get('scheme', 'hls');
        $startAtDate = $request->get('startAtDate', date('Y-m-d'));
        $endAtDate   = $request->get('endAtDate', '');
        $seekTime    = (int)$request->get('seekTime', 0);

        if (!$deviceId) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INPUT);
        }

        $deviceCameraService = new DeviceCameraService();
        return $this->success($deviceCameraService->queryDeviceVodUrlByTime($deviceId, $scheme, $startAtDate,
            $seekTime));
    }

    /**
     * 心跳维护
     *
     * @param Request $request
     * @param int $shopId
     * @param int $id
     * @return JsonResponse
     * @throws Exception
     */
    public function cruiseCameraHeartBeat(Request $request): JsonResponse
    {
        $deviceId = (int)$request->get('deviceId');
        $type     = $request->get('type', '1');
        $scheme   = $request->get('scheme', 'hls');
        $rate     = $request->get('rate', '1000');

        $camera = new CameraFactory($deviceId);

        $data = $camera->getIns()->heartBeat($type, $scheme, $rate);

        return $this->success($data);
    }

    /**
     * 摄像头设备列表-门店搜索项
     * @return JsonResponse
     * @throws Exception
     */
    public function cameraSearch(): JsonResponse
    {
        $data = [
            'guanyuanStatus' => enumToSelection(CodeEnum::SHOP_GUANYUAN_STATUS_TYPE_TEXT),
            'cameraStatus'   => enumToSelection(CodeEnum::SHOP_CAMERA_STATUS_TYPE_TEXT),
        ];
        return $this->success($data);
    }

    /**
     * 摄像头设备列表-门店搜索
     * @param Request $request
     * @return JsonResponse
     */
    public function cruiseCameraLists(Request $request): JsonResponse
    {
        $name           = (string)$request->get('name', ''); // 门店编号/名称
        $shopIds        = (string)$request->get('shopIds', ''); // 门店id，逗号隔开
        $guanyuanStatus = (string)$request->get('guanyuanStatus', ''); // 观远门店状态 1-正常营业 2-暂停营业 3-筹备中 4-选址中
        $cameraStatus   = (string)$request->get('cameraStatus', '');// 摄像头状态 0-缺失 1-在线 2-离线 3-部分在线
        $councilorName  = (string)$request->get('councilorName', '');// 督导名称
        $cruiseName     = (string)$request->get('cruiseName', '');// 稽核名称
        $startTime      = (string)$request->get('startTime', '');// 未巡检日期-开始时间
        $endTime        = (string)$request->get('endTime', '');// 未巡检日期-结束时间
        $pageSize       = (int)$request->get('pageSize', 20);
        $pageNum        = (int)$request->get('pageNum', 1);

        $shopIds        = $shopIds ? explode(',', $shopIds) : [];
        $guanyuanStatus = $guanyuanStatus ? explode(',', $guanyuanStatus) : [];
        $cameraStatus   = strlen($cameraStatus) ? explode(',', $cameraStatus) : [];
        $startTime      = $startTime ? strtotime($startTime) : 0;
        $endTime        = $endTime ? strtotime($endTime . ' 23:59:59') : 0;

        $search = [
            'name'           => $name,
            'shopIds'        => $shopIds,
            'guanyuanStatus' => $guanyuanStatus,
            'cameraStatus'   => $cameraStatus,
            'councilorName'  => $councilorName,
            'cruiseName'     => $cruiseName,
            'startTime'      => $startTime,
            'endTime'        => $endTime,
        ];

        return $this->success(DeviceCameraService::getCameraListByShopIds($search, $pageNum, $pageSize));
    }

}
